using System.Collections.Generic;
using DependencyAnalysis.Internal;

namespace DependencyAnalysis.DataModel
{
    public interface IDependencyModel
    {
        /// <summary>
        /// Reset the dependency model to its initial state and remove all descriptors.
        /// </summary>
        void Clear();

        /// <summary>
        /// Add a descriptor to the model.
        /// </summary>
        /// <typeparam name="T">MemberDescriptor,TypeDescriptor,SubmoduleDescriptor,ModuleDescriptor,DependencyDescriptor</typeparam>
        /// <param name="descriptor"></param>
        void Add<T>(T descriptor) where T : IDescriptor;

        /// <summary>
        /// The dependency structure to query by TypeDescriptor. Contains all afferences to that type.
        /// </summary>
        IDictionary<IDescriptor, ISet<DependencyDescriptor>> DependenciesPerType { get; }

        /// <summary>
        /// The dependency structure to query by SubmoduleDescriptor. Contains all afferences to that submodule.
        /// </summary>
        IDictionary<IDescriptor, ISet<DependencyDescriptor>> DependenciesPerSubmodule { get; }

        /// <summary>
        /// The dependency structure to query by ModuleDescriptor. Contains all afferences to that module.
        /// </summary>
        IDictionary<IDescriptor, ISet<DependencyDescriptor>> DependenciesPerModule { get; }

        /// <summary>
        /// The dependency structure to query by MemberDescriptor. Contains all afferences to that member.
        /// </summary>
        IDictionary<IDescriptor, ISet<DependencyDescriptor>> DependenciesPerMember { get; }

        /// <summary>
        /// The dependency structure to query by TypeDescriptor. Contains all efferences to that type.
        /// </summary>
        IDictionary<IDescriptor, ISet<DependencyDescriptor>> DependenciesPerTypeOut { get; }

        /// <summary>
        /// The dependency structure to query by SubmoduleDescriptor. Contains all efferences to that submodule.
        /// </summary>
        IDictionary<IDescriptor, ISet<DependencyDescriptor>> DependenciesPerSubmoduleOut { get; }

        /// <summary>
        /// The dependency structure to query by ModuleDescriptor. Contains all efferences to that module.
        /// </summary>
        IDictionary<IDescriptor, ISet<DependencyDescriptor>> DependenciesPerModuleOut { get; }

        /// <summary>
        /// The dependency structure to query by MemberDescriptor. Contains all efferences to that member.
        /// </summary>
        IDictionary<IDescriptor, ISet<DependencyDescriptor>> DependenciesPerMemberOut { get; }

        /// <summary>
        /// Contains the instruction for each member of the project
        /// </summary>
        InstructionCache InstructionCache { get; }

        /// <summary>
        /// The project contains all Modules that are marked with the flag IsPartOfProject.
        /// </summary>
        ProjectDescriptor Project { get; }
    }
}